home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / os20 / wb / toolmanager2_0.lha / ToolManager / Source / prefs / menuwindow.c < prev    next >
C/C++ Source or Header  |  1992-09-26  |  12KB  |  464 lines

  1. /*
  2.  * menuwindow.c  V2.0
  3.  *
  4.  * menu edit window handling
  5.  *
  6.  * (c) 1990-1992 Stefan Becker
  7.  */
  8.  
  9. #include "ToolManagerConf.h"
  10.  
  11. /* Menu node */
  12. struct MenuNode {
  13.                   struct Node  mn_Node;
  14.                   char        *mn_Exec;
  15.                   char        *mn_Sound;
  16.                  };
  17.  
  18. /* Window data */
  19. static struct Gadget *gl;             /* Gadget list */
  20. static struct Window *w;              /* Window */
  21. static struct MsgPort *wp;            /* Window user port */
  22. static UWORD ww,wh;                   /* Window size */
  23. static struct MenuNode *CurrentNode;
  24. static ULONG CurrentGadgetNum;
  25. static ReqOpen;
  26. #define WINDOW_IDCMP (IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|BUTTONIDCMP|\
  27.                       STRINGIDCMP|TEXTIDCMP)
  28.  
  29. /* Gadget data */
  30. #define GAD_NAME_STR  0
  31. #define GAD_EXEC_BUT  1
  32. #define GAD_EXEC_TXT  2
  33. #define GAD_SOUND_BUT 3
  34. #define GAD_SOUND_TXT 4
  35. #define GAD_OK        5
  36. #define GAD_CANCEL    6
  37. #define GADGETS       7
  38. static struct GadgetData gdata[GADGETS];
  39.  
  40. /* Gadget tags */
  41. static struct TagItem nametags[]={GTST_String,   NULL,
  42.                                   GTST_MaxChars, 100,
  43.                                   TAG_DONE};
  44.  
  45. static struct TagItem exectags[]={GTTX_Text,   NULL,
  46.                                   GTTX_Border, TRUE,
  47.                                   TAG_DONE};
  48.  
  49. static struct TagItem soundtags[]={GTTX_Text,   NULL,
  50.                                    GTTX_Border, TRUE,
  51.                                    TAG_DONE};
  52.  
  53. /* Init menu edit window */
  54. void InitMenuEditWindow(UWORD left, UWORD fheight)
  55. {
  56.  ULONG tmp,tmp2,maxw1,maxw2;
  57.  ULONG strheight=fheight+2;
  58.  struct GadgetData *gd;
  59.  
  60.  /* Init strings */
  61.  gdata[GAD_OK].name       =AppStrings[MSG_WINDOW_OK_GAD];
  62.  gdata[GAD_CANCEL].name   =AppStrings[MSG_WINDOW_CANCEL_GAD];
  63.  
  64.  /* Calculate maximum label width for string gadgets */
  65.  maxw1=TextLength(&TmpRastPort,AppStrings[MSG_WINDOW_NAME_GAD],
  66.                   strlen(AppStrings[MSG_WINDOW_NAME_GAD]));
  67.  tmp=TextLength(&TmpRastPort,AppStrings[MSG_WINDOW_EXEC_GAD],
  68.                 strlen(AppStrings[MSG_WINDOW_EXEC_GAD]))+2*INTERWIDTH;
  69.  if (tmp > maxw1) maxw1=tmp;
  70.  tmp=TextLength(&TmpRastPort,AppStrings[MSG_WINDOW_SOUND_GAD],
  71.                 strlen(AppStrings[MSG_WINDOW_SOUND_GAD]))+2*INTERWIDTH;
  72.  if (tmp > maxw1) maxw1=tmp;
  73.  maxw1+=INTERWIDTH;
  74.  
  75.  /* Calculate minimal string gadget width */
  76.  ww=TextLength(&TmpRastPort,AppStrings[MSG_MENUWIN_NEWNAME],
  77.                strlen(AppStrings[MSG_MENUWIN_NEWNAME]))+
  78.     maxw1+3*INTERWIDTH;
  79.  
  80.  /* Calculate button gadgets width */
  81.  gd=&gdata[GAD_OK];
  82.  maxw2=TextLength(&TmpRastPort,gd->name,strlen(gd->name));
  83.  gd++;
  84.  if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > maxw2)
  85.   maxw2=tmp;
  86.  maxw2+=2*INTERWIDTH;
  87.  if ((tmp=2*(maxw2+INTERWIDTH)) > ww) ww=tmp;
  88.  
  89.  /* window height */
  90.  wh=4*fheight+5*INTERHEIGHT+6;
  91.  
  92.  /* Init gadgets */
  93.  gd=gdata;
  94.  tmp=WindowTop+INTERHEIGHT;
  95.  tmp2=ww-maxw1-INTERWIDTH;
  96.  
  97.  /* Name string gadget */
  98.  gd->name=AppStrings[MSG_WINDOW_NAME_GAD];
  99.  gd->type=STRING_KIND;
  100.  gd->flags=PLACETEXT_LEFT;
  101.  gd->tags=nametags;
  102.  gd->left=maxw1+left;
  103.  gd->top=tmp;
  104.  gd->width=tmp2;
  105.  gd->height=strheight;
  106.  tmp+=strheight+INTERHEIGHT;
  107.  
  108.  /* Exec object button gadget */
  109.  gd++;
  110.  gd->name=AppStrings[MSG_WINDOW_EXEC_GAD];
  111.  gd->type=BUTTON_KIND;
  112.  gd->flags=PLACETEXT_IN;
  113.  gd->left=left;
  114.  gd->top=tmp;
  115.  gd->width=maxw1-INTERWIDTH;
  116.  gd->height=strheight;
  117.  
  118.  /* Exec object text gadget */
  119.  gd++;
  120.  gd->type=TEXT_KIND;
  121.  gd->tags=exectags;
  122.  gd->left=maxw1+left;
  123.  gd->top=tmp;
  124.  gd->width=tmp2;
  125.  gd->height=strheight;
  126.  tmp+=strheight+INTERHEIGHT;
  127.  
  128.  /* Sound object button gadget */
  129.  gd++;
  130.  gd->name=AppStrings[MSG_WINDOW_SOUND_GAD];
  131.  gd->type=BUTTON_KIND;
  132.  gd->flags=PLACETEXT_IN;
  133.  gd->left=left;
  134.  gd->top=tmp;
  135.  gd->width=maxw1-INTERWIDTH;
  136.  gd->height=strheight;
  137.  
  138.  /* Sound object text gadget */
  139.  gd++;
  140.  gd->type=TEXT_KIND;
  141.  gd->tags=soundtags;
  142.  gd->left=maxw1+left;
  143.  gd->top=tmp;
  144.  gd->width=tmp2;
  145.  gd->height=strheight;
  146.  tmp+=strheight+INTERHEIGHT;
  147.  
  148.  /* OK button gadget */
  149.  gd++;
  150.  gd->type=BUTTON_KIND;
  151.  gd->flags=PLACETEXT_IN;
  152.  gd->left=left;
  153.  gd->top=tmp;
  154.  gd->width=maxw2;
  155.  gd->height=fheight;
  156.  
  157.  /* Cancel button gadget */
  158.  gd++;
  159.  gd->type=BUTTON_KIND;
  160.  gd->flags=PLACETEXT_IN;
  161.  gd->left=ww-maxw2-INTERWIDTH+left;
  162.  gd->top=tmp;
  163.  gd->width=maxw2;
  164.  gd->height=fheight;
  165. }
  166.  
  167. /* Free menu node */
  168. void FreeMenuNode(struct Node *node)
  169. {
  170.  struct MenuNode *mn=node;
  171.  char *s;
  172.  
  173.  if (s=mn->mn_Node.ln_Name) free(s);
  174.  if (s=mn->mn_Exec) free(s);
  175.  if (s=mn->mn_Sound) free(s);
  176.  
  177.  /* Free node */
  178.  FreeMem(mn,sizeof(struct MenuNode));
  179. }
  180.  
  181. /* Copy menu node */
  182. struct Node *CopyMenuNode(struct Node *node)
  183. {
  184.  struct MenuNode *mn,*orignode=node;
  185.  
  186.  /* Alloc memory for exec node */
  187.  if (mn=AllocMem(sizeof(struct MenuNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  188.  
  189.   /* Got an old node? */
  190.   if (orignode) {
  191.    /* Yes, copy it */
  192.    if ((!orignode->mn_Node.ln_Name || (mn->mn_Node.ln_Name=
  193.                                         strdup(orignode->mn_Node.ln_Name))) &&
  194.        (!orignode->mn_Exec || (mn->mn_Exec=strdup(orignode->mn_Exec))) &&
  195.        (!orignode->mn_Sound || (mn->mn_Sound=strdup(orignode->mn_Sound))))
  196.     return(mn);
  197.   } else
  198.    /* No, set defaults */
  199.    if (mn->mn_Node.ln_Name=strdup(AppStrings[MSG_MENUWIN_NEWNAME]))
  200.     /* Return pointer to new node */
  201.     return(mn);
  202.  
  203.   FreeMenuNode((struct Node *) mn);
  204.  }
  205.  /* Call failed */
  206.  return(NULL);
  207. }
  208.  
  209. /* Activate name string gadget */
  210. static void ActivateNameGadget(void)
  211. {
  212.  ActivateGadget(gdata[GAD_NAME_STR].gadget,w,NULL);
  213. }
  214.  
  215. /* Open menu edit window */
  216. BOOL OpenMenuEditWindow(struct Node *node, struct Window *parent)
  217. {
  218.  /* Copy node */
  219.  if (CurrentNode=CopyMenuNode(node)) {
  220.   /* Set tags */
  221.   nametags[0].ti_Data=CurrentNode->mn_Node.ln_Name;
  222.   exectags[0].ti_Data=CurrentNode->mn_Exec;
  223.   soundtags[0].ti_Data=CurrentNode->mn_Sound;
  224.  
  225.   /* Create gadgets */
  226.   if (gl=CreateGadgetList(gdata,GADGETS)) {
  227.    /* Open window */
  228.    if (w=OpenWindowTags(NULL,WA_Left,parent->LeftEdge,
  229.                              WA_Top,parent->TopEdge+WindowTop,
  230.                              WA_InnerWidth,ww,
  231.                              WA_InnerHeight,wh,
  232.                              WA_AutoAdjust,TRUE,
  233.                              WA_Title,AppStrings[MSG_MENUWIN_TITLE],
  234.                              WA_PubScreen,PublicScreen,
  235.                              WA_Flags,WFLG_CLOSEGADGET|WFLG_DRAGBAR|
  236.                                       WFLG_DEPTHGADGET|WFLG_RMBTRAP|
  237.                                       WFLG_ACTIVATE,
  238.                              TAG_DONE)) {
  239.     /* Add gadgets to window */
  240.     AddGList(w,gl,(UWORD) -1,(UWORD) -1,NULL);
  241.     RefreshGList(gl,w,NULL,(UWORD) -1);
  242.     GT_RefreshWindow(w,NULL);
  243.  
  244.     /* Activate name string gadget */
  245.     ActivateNameGadget();
  246.  
  247.     /* Set local variables */
  248.     w->UserPort=IDCMPPort;
  249.     w->UserData=HandleMenuEditWindowIDCMP;
  250.     ModifyIDCMP(w,WINDOW_IDCMP);
  251.     CurrentWindow=w;
  252.     ReqOpen=FALSE;
  253.  
  254.     /* All OK. */
  255.     return(TRUE);
  256.    }
  257.    FreeGadgets(gl);
  258.   }
  259.   FreeMenuNode((struct Node *) CurrentNode);
  260.  }
  261.  /* Call failed */
  262.  return(FALSE);
  263. }
  264.  
  265. /* Close menu edit window */
  266. static void CloseMenuEditWindow(void)
  267. {
  268.  /* Free resources */
  269.  RemoveGList(w,gl,(UWORD) -1);
  270.  CloseWindowSafely(w);
  271.  FreeGadgets(gl);
  272. }
  273.  
  274. /* Handle menu edit window IDCMP events */
  275. void *HandleMenuEditWindowIDCMP(struct IntuiMessage *msg)
  276. {
  277.  struct Node *NewNode=NULL;
  278.  
  279.  /* Which IDCMP class? */
  280.  switch (msg->Class) {
  281.   case IDCMP_CLOSEWINDOW:   NewNode=(struct Node *) -1;
  282.                             FreeMenuNode((struct Node *) CurrentNode);
  283.                             break;
  284.   case IDCMP_REFRESHWINDOW: GT_BeginRefresh(w);
  285.                             GT_EndRefresh(w,TRUE);
  286.                             break;
  287.   case IDCMP_GADGETUP:
  288.    switch (((struct Gadget *) msg->IAddress)->GadgetID) {
  289.     case GAD_NAME_STR:  /* ActivateNameGadget(); */
  290.                         break;
  291.     case GAD_EXEC_BUT:  if (!ReqOpen) {
  292.                          /* Save gadget number */
  293.                          CurrentGadgetNum=GAD_EXEC_TXT;
  294.  
  295.                          /* Open list requester */
  296.                          if (OpenListRequester(LISTREQ_EXEC,w)) {
  297.                           /* Disable window */
  298.                           DisableWindow(w);
  299.  
  300.                           /* Set update function */
  301.                           UpdateWindow=UpdateMenuEditWindow;
  302.                           ReqOpen=TRUE;
  303.                          } else
  304.                           ActivateNameGadget();
  305.                         }
  306.                         break;
  307.     case GAD_EXEC_TXT:
  308.                         break;
  309.     case GAD_SOUND_BUT: if (!ReqOpen) {
  310.                          /* Save gadget number */
  311.                          CurrentGadgetNum=GAD_SOUND_TXT;
  312.  
  313.                          /* Open list requester */
  314.                          if (OpenListRequester(LISTREQ_SOUND,w)) {
  315.                           /* Disable window */
  316.                           DisableWindow(w);
  317.  
  318.                           /* Set update function */
  319.                           UpdateWindow=UpdateMenuEditWindow;
  320.                           ReqOpen=TRUE;
  321.                          } else
  322.                           ActivateNameGadget();
  323.                         }
  324.                         break;
  325.     case GAD_SOUND_TXT:
  326.                         break;
  327.     case GAD_OK: {
  328.      char *s;
  329.  
  330.      /* Free old string */
  331.      if (s=CurrentNode->mn_Node.ln_Name) free(s);
  332.  
  333.      /* Duplicate new string */
  334.      if ((CurrentNode->mn_Node.ln_Name=
  335.            DuplicateBuffer(gdata[GAD_NAME_STR].gadget)) != (char *) -1)
  336.       NewNode=CurrentNode;
  337.      else {
  338.       /* Couldn't copy strings */
  339.       NewNode=(struct Node *) -1;
  340.       CurrentNode->mn_Node.ln_Name=NULL;
  341.       FreeMenuNode((struct Node *) CurrentNode);
  342.      }
  343.     }
  344.     break;
  345.     case GAD_CANCEL:    NewNode=(struct Node *) -1;
  346.                         FreeMenuNode((struct Node *) CurrentNode);
  347.                         break;
  348.    }
  349.    break;
  350.  }
  351.  
  352.  /* Close window? */
  353.  if (NewNode) {
  354.   /* Yes. But first reply message!!! */
  355.   GT_ReplyIMsg(msg);
  356.   CloseMenuEditWindow();
  357.  }
  358.  
  359.  return(NewNode);
  360. }
  361.  
  362. /* Update Menu edit window */
  363. void UpdateMenuEditWindow(void *data)
  364. {
  365.  /* Got data? */
  366.  if (data != LREQRET_CANCEL) {
  367.   char *new;
  368.  
  369.   /* Selected something? */
  370.   new=(data == LREQRET_NOSELECT) ? NULL : ((struct Node *) data)->ln_Name;
  371.  
  372.   /* Duplicate name */
  373.   if (!new || (new=strdup(new))) {
  374.    char *old;
  375.  
  376.    /* Exec object? */
  377.    if (CurrentGadgetNum==GAD_EXEC_TXT) {
  378.     /* Yes. Set new Exec name */
  379.     old=CurrentNode->mn_Exec;
  380.     CurrentNode->mn_Exec=new;
  381.    } else {
  382.     /* No. Set new Sound name */
  383.     old=CurrentNode->mn_Sound;
  384.     CurrentNode->mn_Sound=new;
  385.    }
  386.  
  387.    /* Free old string */
  388.    if (old) free(old);
  389.  
  390.    /* Set new text */
  391.    GT_SetGadgetAttrs(gdata[CurrentGadgetNum].gadget,w,NULL,GTTX_Text,new,
  392.                                                            TAG_DONE);
  393.   }
  394.  }
  395.  
  396.  /* Activate name string gadget */
  397.  ActivateNameGadget();
  398.  
  399.  /* Enable window */
  400.  EnableWindow(w,WINDOW_IDCMP);
  401.  
  402.  /* Restore update function pointer */
  403.  UpdateWindow=UpdateMainWindow;
  404.  CurrentWindow=w;
  405.  ReqOpen=FALSE;
  406. }
  407.  
  408. /* Read TMMO IFF chunk into Menu node */
  409. struct Node *ReadMenuNode(UBYTE *buf)
  410. {
  411.  struct MenuNode *mn;
  412.  
  413.  /* Allocate memory for node */
  414.  if (mn=AllocMem(sizeof(struct MenuNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  415.   struct MenuPrefsObject *mpo=buf;
  416.   ULONG sbits=mpo->mpo_StringBits;
  417.   UBYTE *ptr=mpo+1;
  418.  
  419.   if ((!(sbits & MOPO_NAME) || (mn->mn_Node.ln_Name=GetConfigStr(&ptr))) &&
  420.       (!(sbits & MOPO_EXEC) || (mn->mn_Exec=GetConfigStr(&ptr))) &&
  421.       (!(sbits & MOPO_SOUND) || (mn->mn_Sound=GetConfigStr(&ptr))))
  422.    /* All OK. */
  423.    return(mn);
  424.  
  425.   /* Call failed */
  426.   FreeMenuNode((struct Node *) mn);
  427.  }
  428.  return(NULL);
  429. }
  430.  
  431. /* Write Menu node to TMMO IFF chunk */
  432. BOOL WriteMenuNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  433. {
  434.  struct MenuNode *mn=node;
  435.  struct MenuPrefsObject *mpo=buf;
  436.  ULONG sbits=0;
  437.  UBYTE *ptr=mpo+1;
  438.  
  439.  /* Copy strings */
  440.  if (PutConfigStr(mn->mn_Node.ln_Name,&ptr)) sbits|=MOPO_NAME;
  441.  if (PutConfigStr(mn->mn_Exec,&ptr)) sbits|=MOPO_EXEC;
  442.  if (PutConfigStr(mn->mn_Sound,&ptr)) sbits|=MOPO_SOUND;
  443.  
  444.  /* set string bits */
  445.  mpo->mpo_StringBits=sbits;
  446.  
  447.  /* calculate length */
  448.  sbits=ptr-buf;
  449.  
  450.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  451.  
  452.  /* Open chunk */
  453.  if (PushChunk(iff,0,ID_TMMO,sbits)) return(FALSE);
  454.  
  455.  /* Write chunk */
  456.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  457.  
  458.  /* Close chunk */
  459.  if (PopChunk(iff)) return(FALSE);
  460.  
  461.  /* All OK. */
  462.  return(TRUE);
  463. }
  464.